/**
 * 有关雨点项目的各类指令。
 * 在 bower.json 中加入git repo的链接，即可引用。
 *
 */

angular.module('yudianDirectives', []).
    /**
     * 当点击提交时，如果有invalid input，则自动focus在上
     */
    directive('accessibleForm', function() {
        return {
            restrict: 'A',
            link: function(scope, elem) {

                // set up event handler on the form element
                elem.on('submit', function() {

                    // find the first invalid element
                    var firstInvalid = elem[0].querySelector('.ng-invalid');

                    // if we find one, set focus
                    if (firstInvalid) {
                        firstInvalid.focus();
                    }
                });
            }
        };
    }).
    /**
     * 获取验证码功能的指令
     * 可设定初始文字，以及倒计时时间
     * 当点击后，出现倒计时文字，同时增加 disabled class
     * TODO: 可配置倒计时内容
     */
    directive('telCodeButton', function() {
        return {
            restrict: 'A',
            scope: {
                text: '@',
                delaySec: '@',
                performAction: '&'
            },
            link: function(scope, elem, attr, ngModel) {
                scope.initText = elem.attr("init-text") ? elem.attr("init-text") : '获取';

                // delaySec == 0, means it is available
                scope.delaySec = 0;
                elem.text(scope.initText);
                scope.startCountDown = function() {
                    var countDown = function() {
                        if (scope.delaySec == 0) {
                            clearInterval(scope.intervalId);
                            elem.text(scope.initText);
                            elem.removeClass("disabled");
                        } else {
                            elem.addClass("disabled");
                            var text = String(scope.delaySec) + 's';
                            elem.text(text);
                            scope.delaySec -= 1;
                        }
                    };
                    scope.delaySec = 120;
                    countDown(); // disable the button at once
                    scope.intervalId = setInterval(countDown, 1000);
                };
                elem.bind('click', function($event) {
                    console.log("button clicked!");
                    if (scope.delaySec == 0) {
                        scope.performAction({
                            arg1: scope.startCountDown
                        });
                    }
                    $event.preventDefault();
                });
            }
        };
    }).
    /**
     * 允奕系统要求的密码强度验证
     * 6～20位英文、数字、特殊符号，且至少包含两种
     * `form`.`field`.$error.passwordStrengthValidation 表示该validation的结果
     */
    directive('passwordStrengthValidation', function() {
        return {
            require: 'ngModel',
            link: function(scope, elem, attr, ngModel) {
                var pattern = /^[a-zA-Z0-9`~!@#$%^&*()_+\-=|{}\\\[\]:";'<>?,./]{6,20}$/;
                var pattern_wd = /^[a-zA-Z]{6,20}$/;
                var pattern_num = /^[0-9]{6,20}$/;
                var pattern_syb = /^[`~!@#$%^&*()_+\-=|{}\\\[\]:";'<>?,./]{6,20}$/;

                var checkPassword = function(pass) {
                    //exclude password contains only word, number or symbol, ie. 2 of 3 kinds at least
                    if (pattern_wd.test(pass) || pattern_num.test(pass) || pattern_syb.test(pass)) {
                        return false;
                    } else {
                        return pattern.test(pass);
                    }
                };

                //For DOM -> model validation
                ngModel.$parsers.unshift(function(value) {
                    var valid = checkPassword(value);
                    ngModel.$setValidity('passwordStrengthValidation', valid);
                    return valid ? value : undefined;
                });

                //For model -> DOM validation
                ngModel.$formatters.unshift(function(value) {
                    ngModel.$setValidity('passwordStrengthValidation', checkPassword(value));
                    return value;
                });
            }
        };
    }).
    /**
     * 身份证检验的指令
     * `form`.`field`.$error.idCardValidation 表示该validation的结果
     */
    directive('idCardValidation', function() {
        return {
            require: 'ngModel',
            link: function(scope, elem, attr, ngModel) {
                var checkIdCard = function(code) {
                    if (code === undefined)
                        return false;
                    code = code.toUpperCase(code);
                    var city = {
                        11: "北京",
                        12: "天津",
                        13: "河北",
                        14: "山西",
                        15: "内蒙古",
                        21: "辽宁",
                        22: "吉林",
                        23: "黑龙江 ",
                        31: "上海",
                        32: "江苏",
                        33: "浙江",
                        34: "安徽",
                        35: "福建",
                        36: "江西",
                        37: "山东",
                        41: "河南",
                        42: "湖北 ",
                        43: "湖南",
                        44: "广东",
                        45: "广西",
                        46: "海南",
                        50: "重庆",
                        51: "四川",
                        52: "贵州",
                        53: "云南",
                        54: "西藏 ",
                        61: "陕西",
                        62: "甘肃",
                        63: "青海",
                        64: "宁夏",
                        65: "新疆",
                        71: "台湾",
                        81: "香港",
                        82: "澳门",
                        91: "国外 "
                    };
                    var tip = "";
                    var pass = true;

                    if (!code || !/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(code)) {
                        tip = "身份证号格式错误";
                        pass = false;
                    } else if (!city[code.substr(0, 2)]) {
                        tip = "地址编码错误";
                        pass = false;
                    } else {
                        //18位身份证需要验证最后一位校验位
                        if (code.length == 18) {
                            code = code.split('');
                            //∑(ai×Wi)(mod 11)
                            //加权因子
                            var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
                            //校验位
                            var parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2];
                            var sum = 0;
                            var ai = 0;
                            var wi = 0;
                            for (var i = 0; i < 17; i++) {
                                ai = code[i];
                                wi = factor[i];
                                sum += ai * wi;
                            }
                            var last = parity[sum % 11];
                            if (parity[sum % 11] != code[17]) {
                                tip = "校验位错误";
                                pass = false;
                            }
                        }
                    }
                    // if(!pass) alert(tip);
                    return pass;
                };

                //For DOM -> model validation
                ngModel.$parsers.unshift(function(value) {
                    var valid = checkIdCard(value);
                    ngModel.$setValidity('idCardValidation', valid);
                    return valid ? value : undefined;
                });

                //For model -> DOM validation
                ngModel.$formatters.unshift(function(value) {
                    ngModel.$setValidity('idCardValidation', checkIdCard(value));
                    return value;
                });
            }
        };
    });
